﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate;
using System.Collections.Specialized;
using NHibernate.Criterion;

namespace Akronus.TaskScheduler.NhbDataService
{
    /// <summary>
    /// The implementation of <see cref="ITaskInfoDataService"/> interface. This service is used to fetch and save the information about task state.
    /// </summary>
    public class TaskInfoDataService : ITaskInfoDataService
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="TaskInfoDataService"/> class.
        /// </summary>
        public TaskInfoDataService(string connectionString)
        {
            this.connectionString = connectionString;
        }

        protected virtual SessionManager CreateSessionManager(bool readOnly)
        {
            return new SessionManager(this.connectionString, readOnly);
        }

        /// <summary>
        /// The connection string used to connect to the database.
        /// </summary>
        protected string connectionString;

        /// <summary>
        /// Saves the task info.
        /// </summary>
        /// <param name="taskInfo">The task info.</param>
        public void SaveTaskInfo(TaskInfo taskInfo)
        {
            using (var sm = CreateSessionManager(false))
            {
                var oldTaskInfo = sm.Session.Get<TaskInfo>(taskInfo.Name);
                if (oldTaskInfo != null)
                {
                    sm.Session.Evict(oldTaskInfo);
                    sm.Session.Update(taskInfo);
                }
                else
                {
                    sm.Session.Save(taskInfo);
                }
                sm.Commit();
            }
        }

        /// <summary>
        /// Gets the task infos.
        /// </summary>
        /// <returns>The task infos.</returns>
        public IList<TaskInfo> GetTaskInfos()
        {
            using (var sm = CreateSessionManager(true))
            {
                ICriteria criteria = sm.Session.CreateCriteria(typeof(TaskInfo));
                return criteria.AddOrder(NHibernate.Criterion.Order.Desc("Name")).List<TaskInfo>();
            }
        }

        /// <summary>
        /// Gets the task info.
        /// </summary>
        /// <param name="taskName">Name of the task.</param>
        /// <returns>The task info.</returns>
        public TaskInfo GetTaskInfo(string taskName)
        {
            using (var sm = CreateSessionManager(true))
            {
                return sm.Session.Get<TaskInfo>(taskName);
            }
        }
    }
}
